#ifndef __SYLAR_IOMANAGER_H__
#define __SYLAR_IOMANAGER_H__

#include "scheduler.h"
#include "timer.h"

namespace sylar{
    

class IOManager : public Scheduler, public TimerManager{
public:
    typedef std::shared_ptr<IOManager> ptr;
    typedef RWMutex RWMutexType;

    enum Event{
        NONE    = 0x0,
        READ    = 0x1,	//EPOLLIN
        WRITE   = 0x4,	//EPOLLOUT
    };
private:    
    struct FdContext{	// 文件的事件上下文
        typedef Mutex MutexType;	
        struct EventContext {	// 事件上下文
            Scheduler* scheduler = nullptr;	// 调度器
            Fiber::ptr fiber;				// 事件回调协程
            std::function<void()> cb;		// 事件回调函数
        };
		/**
		 * @brief 根据事件类型得到事件上下文
		 */
        EventContext& getContext(Event event);	
		/**
		 * @brief 重置事件的上下文
		 */
        void resetContext(EventContext& ctx);
		/**
		 * @brief 唤醒对应事件的回调协程/函数
		 */
        void triggerEvent(Event event);

        EventContext read;	//读事件上下文
        EventContext write;	//写事件上下文
        int fd = 0;			//文件描述符
        Event events = NONE;//已注册事件
        MutexType mutex;	//互斥锁
    };
public:
    IOManager(size_t threads = 1, bool use_caller = true, const std::string name = "");
    ~IOManager();
	/**
	 * @brief 向文件fd注册event事件
	 */
    int addEvent(int fd, Event event, std::function<void()> cb = nullptr);
	/**
	 * @brief 从文件fd删除event对应事件
	 */
    bool delEvent(int fd, Event event);
    /**
	 * @brief 取消对应时间, 立即执行对应回调
	 */
	bool cancelEvent(int fd, Event event);
	/**
	 * @brief 取消所有事件, 立即执行所有的回调
	 */
    bool cancelAll(int fd);

    static IOManager* GetThis();
protected:
	/**
	 * @brief 唤醒事件
	 */
    void tickle() override;
	/**
	 * @brief 判断是否可以停止
	 */
    bool stopping() override;
	bool stopping(uint64_t& timeout);
	/**
	 * @brief 空闲线程
	 */
    void idle() override;
	/**
	 * @brief 新加入一个定时器到队首, 需要唤醒epollwait
	 */
	void onTimerInsertedAtFront() override;
	/**
	 * @brief 扩大支持fd的范围
	 */
    void contextResize(size_t size);
private:
    int m_epfd;				//epoll文件描述符
    int m_tickleFds[2];		//epoll的唤醒管道

    std::atomic<size_t> m_pendingEventCount = {0};	//等待事件的个数
    RWMutexType m_mutex;							//互斥锁
    std::vector<FdContext*> m_fdContexts;			//文件的事件上下文

};

}   //namespace sylar

#endif